<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>HTTP缓存 | hishion blog</title>
    <meta name="generator" content="VuePress 1.8.2">
    <link rel="icon" href="/blog/img/favicon.ico">
    <meta name="description" content="web front-end development engineer">
    <meta name="title" content="hishion blog">
    <meta name="keywords" content="小程序,Vue,uni-app,LESS/SCSS,Git">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
    
    <link rel="preload" href="/blog/assets/css/0.styles.85454e8d.css" as="style"><link rel="preload" href="/blog/assets/js/app.17d93a93.js" as="script"><link rel="preload" href="/blog/assets/js/2.d5810a70.js" as="script"><link rel="preload" href="/blog/assets/js/53.c398474b.js" as="script"><link rel="prefetch" href="/blog/assets/js/10.a2c8b9d7.js"><link rel="prefetch" href="/blog/assets/js/11.6316d0fd.js"><link rel="prefetch" href="/blog/assets/js/12.927e97fe.js"><link rel="prefetch" href="/blog/assets/js/13.5647b041.js"><link rel="prefetch" href="/blog/assets/js/14.2ae9363a.js"><link rel="prefetch" href="/blog/assets/js/15.00f0b12c.js"><link rel="prefetch" href="/blog/assets/js/16.cf70fbc0.js"><link rel="prefetch" href="/blog/assets/js/17.03f65a2a.js"><link rel="prefetch" href="/blog/assets/js/18.eab9c888.js"><link rel="prefetch" href="/blog/assets/js/19.41e2fb9c.js"><link rel="prefetch" href="/blog/assets/js/20.a81ff0d7.js"><link rel="prefetch" href="/blog/assets/js/21.8f4e6ef9.js"><link rel="prefetch" href="/blog/assets/js/22.33273307.js"><link rel="prefetch" href="/blog/assets/js/23.b9ccad42.js"><link rel="prefetch" href="/blog/assets/js/24.925b6f8f.js"><link rel="prefetch" href="/blog/assets/js/25.09121221.js"><link rel="prefetch" href="/blog/assets/js/26.93b4179f.js"><link rel="prefetch" href="/blog/assets/js/27.248627a6.js"><link rel="prefetch" href="/blog/assets/js/28.a76943a2.js"><link rel="prefetch" href="/blog/assets/js/29.56872daa.js"><link rel="prefetch" href="/blog/assets/js/3.c69e6cb7.js"><link rel="prefetch" href="/blog/assets/js/30.175b2658.js"><link rel="prefetch" href="/blog/assets/js/31.d027670c.js"><link rel="prefetch" href="/blog/assets/js/32.040794e0.js"><link rel="prefetch" href="/blog/assets/js/33.dd9eea2e.js"><link rel="prefetch" href="/blog/assets/js/34.2b31e291.js"><link rel="prefetch" href="/blog/assets/js/35.009bbce8.js"><link rel="prefetch" href="/blog/assets/js/36.ecb36989.js"><link rel="prefetch" href="/blog/assets/js/37.282a8534.js"><link rel="prefetch" href="/blog/assets/js/38.e29d954d.js"><link rel="prefetch" href="/blog/assets/js/39.e071deb9.js"><link rel="prefetch" href="/blog/assets/js/4.20ff38eb.js"><link rel="prefetch" href="/blog/assets/js/40.e30e040e.js"><link rel="prefetch" href="/blog/assets/js/41.f9beaf4c.js"><link rel="prefetch" href="/blog/assets/js/42.631fa7df.js"><link rel="prefetch" href="/blog/assets/js/43.de052ada.js"><link rel="prefetch" href="/blog/assets/js/44.b9d90c8b.js"><link rel="prefetch" href="/blog/assets/js/45.9edc6da4.js"><link rel="prefetch" href="/blog/assets/js/46.43221d60.js"><link rel="prefetch" href="/blog/assets/js/47.70bd2046.js"><link rel="prefetch" href="/blog/assets/js/48.f2da250c.js"><link rel="prefetch" href="/blog/assets/js/49.db6466ad.js"><link rel="prefetch" href="/blog/assets/js/5.413bc4a0.js"><link rel="prefetch" href="/blog/assets/js/50.465c1401.js"><link rel="prefetch" href="/blog/assets/js/51.25711c0b.js"><link rel="prefetch" href="/blog/assets/js/52.c3dd4c01.js"><link rel="prefetch" href="/blog/assets/js/54.1ff939f2.js"><link rel="prefetch" href="/blog/assets/js/55.d00053e3.js"><link rel="prefetch" href="/blog/assets/js/56.4978060f.js"><link rel="prefetch" href="/blog/assets/js/57.b9b8c161.js"><link rel="prefetch" href="/blog/assets/js/58.d67ad12f.js"><link rel="prefetch" href="/blog/assets/js/59.3a1f358e.js"><link rel="prefetch" href="/blog/assets/js/6.747c84d7.js"><link rel="prefetch" href="/blog/assets/js/60.7b70acc9.js"><link rel="prefetch" href="/blog/assets/js/61.43c54fc8.js"><link rel="prefetch" href="/blog/assets/js/62.d27744a0.js"><link rel="prefetch" href="/blog/assets/js/63.73378bfc.js"><link rel="prefetch" href="/blog/assets/js/64.060c996e.js"><link rel="prefetch" href="/blog/assets/js/65.747c9a84.js"><link rel="prefetch" href="/blog/assets/js/66.2a577ef9.js"><link rel="prefetch" href="/blog/assets/js/67.94620d6a.js"><link rel="prefetch" href="/blog/assets/js/68.3cf29532.js"><link rel="prefetch" href="/blog/assets/js/69.9e992128.js"><link rel="prefetch" href="/blog/assets/js/7.7a113c37.js"><link rel="prefetch" href="/blog/assets/js/70.0bf5d79a.js"><link rel="prefetch" href="/blog/assets/js/71.3c940d64.js"><link rel="prefetch" href="/blog/assets/js/72.b39fd551.js"><link rel="prefetch" href="/blog/assets/js/73.b22cb822.js"><link rel="prefetch" href="/blog/assets/js/74.f06bc4d1.js"><link rel="prefetch" href="/blog/assets/js/75.b7bdb0f0.js"><link rel="prefetch" href="/blog/assets/js/76.1dab014e.js"><link rel="prefetch" href="/blog/assets/js/77.7edba438.js"><link rel="prefetch" href="/blog/assets/js/8.eb2c369b.js"><link rel="prefetch" href="/blog/assets/js/9.8d45fb33.js">
    <link rel="stylesheet" href="/blog/assets/css/0.styles.85454e8d.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/blog/" class="home-link router-link-active"><!----> <span class="site-name">hishion blog</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/blog/" class="nav-link">
  首页
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="文章" class="dropdown-title"><span class="title">文章</span> <span class="arrow down"></span></button> <button type="button" aria-label="文章" class="mobile-dropdown-title"><span class="title">文章</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/basic/" class="nav-link">
  前端基础
</a></li><li class="dropdown-item"><!----> <a href="/blog/mp/" class="nav-link">
  小程序
</a></li><li class="dropdown-item"><!----> <a href="/blog/vue/" class="nav-link">
  Vue
</a></li><li class="dropdown-item"><!----> <a href="/blog/uni/life.html" class="nav-link">
  uni-app
</a></li><li class="dropdown-item"><!----> <a href="/blog/scss/" class="nav-link">
  SCSS/LESS
</a></li><li class="dropdown-item"><!----> <a href="/blog/git/" class="nav-link">
  Git
</a></li><li class="dropdown-item"><!----> <a href="/blog/standard/" class="nav-link">
  前端编码规范
</a></li><li class="dropdown-item"><!----> <a href="/blog/tool/" class="nav-link">
  工具
</a></li><li class="dropdown-item"><!----> <a href="/blog/http/" class="nav-link router-link-active">
  网络
</a></li><li class="dropdown-item"><!----> <a href="/blog/linux/" class="nav-link">
  Linux
</a></li><li class="dropdown-item"><!----> <a href="/blog/graphql/" class="nav-link">
  GraphQL
</a></li><li class="dropdown-item"><!----> <a href="/blog/other/" class="nav-link">
  其他
</a></li></ul></div></div><div class="nav-item"><a href="https://gitee.com/hishion.com" target="_blank" rel="noopener noreferrer" class="nav-link external">
  Gitee
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://github.com/weixisheng" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/blog/" class="nav-link">
  首页
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="文章" class="dropdown-title"><span class="title">文章</span> <span class="arrow down"></span></button> <button type="button" aria-label="文章" class="mobile-dropdown-title"><span class="title">文章</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/blog/basic/" class="nav-link">
  前端基础
</a></li><li class="dropdown-item"><!----> <a href="/blog/mp/" class="nav-link">
  小程序
</a></li><li class="dropdown-item"><!----> <a href="/blog/vue/" class="nav-link">
  Vue
</a></li><li class="dropdown-item"><!----> <a href="/blog/uni/life.html" class="nav-link">
  uni-app
</a></li><li class="dropdown-item"><!----> <a href="/blog/scss/" class="nav-link">
  SCSS/LESS
</a></li><li class="dropdown-item"><!----> <a href="/blog/git/" class="nav-link">
  Git
</a></li><li class="dropdown-item"><!----> <a href="/blog/standard/" class="nav-link">
  前端编码规范
</a></li><li class="dropdown-item"><!----> <a href="/blog/tool/" class="nav-link">
  工具
</a></li><li class="dropdown-item"><!----> <a href="/blog/http/" class="nav-link router-link-active">
  网络
</a></li><li class="dropdown-item"><!----> <a href="/blog/linux/" class="nav-link">
  Linux
</a></li><li class="dropdown-item"><!----> <a href="/blog/graphql/" class="nav-link">
  GraphQL
</a></li><li class="dropdown-item"><!----> <a href="/blog/other/" class="nav-link">
  其他
</a></li></ul></div></div><div class="nav-item"><a href="https://gitee.com/hishion.com" target="_blank" rel="noopener noreferrer" class="nav-link external">
  Gitee
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://github.com/weixisheng" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div> <!----></nav>  <ul class="sidebar-links"><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>前端基础</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>小程序</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>Vue</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>SCSS/LESS</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>Git知识</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>前端规范</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>工具</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>Linux知识</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>GraphQL</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading open"><span>网络知识</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/blog/http/" aria-current="page" class="sidebar-link">GET和POST的区别</a></li><li><a href="/blog/http/accelerate.html" class="sidebar-link">加速Github访问</a></li><li><a href="/blog/http/cache.html" aria-current="page" class="active sidebar-link">HTTP缓存</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/blog/http/cache.html#浏览器缓存位置" class="sidebar-link">浏览器缓存位置</a></li><li class="sidebar-sub-header"><a href="/blog/http/cache.html#强缓存" class="sidebar-link">强缓存</a></li><li class="sidebar-sub-header"><a href="/blog/http/cache.html#协商缓存" class="sidebar-link">协商缓存</a></li></ul></li><li><a href="/blog/http/http2.html" class="sidebar-link">HTTP/2</a></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>其他</span> <span class="arrow right"></span></p> <!----></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="http缓存"><a href="#http缓存" class="header-anchor">#</a> HTTP缓存</h1> <p>合理的请求缓存能优化性能！
缓存分为强缓存和协商缓存</p> <h2 id="浏览器缓存位置"><a href="#浏览器缓存位置" class="header-anchor">#</a> 浏览器缓存位置</h2> <ul><li>Service Worker</li></ul> <p>让 JS 运行在主线程之外，脱离了浏览器的窗体，常见的有<code>离线缓存</code>、<code>消息推送</code>和<code>网络代理</code>。</p> <ul><li>Memory Cache</li></ul> <p>内存缓存，效率最快，但是存活时间短，当渲染进程结束后，内存缓存就不存在了。</p> <ul><li>Disk Cache</li></ul> <p>磁盘缓存，存取效率比内存缓存慢，存活时间长、存储容量大。</p> <p>比较大的JS、CSS文件会存到磁盘，反之在内存；内存使用率较高的时候，文件优先进入磁盘。</p> <ul><li>Push Cache</li></ul> <p>推送缓存，HTTP/2的内容。</p> <h2 id="强缓存"><a href="#强缓存" class="header-anchor">#</a> 强缓存</h2> <p>不需要发送HTTP请求，通过检查相应的字段判断，HTTP/1.0使用的是Expires，HTTP/1.1使用的是Cache-Control。</p> <ul><li>Expires</li></ul> <p>即过期时间，存在于服务端返回的响应头中，告诉浏览器在这个过期时间之前可以直接从缓存里面获取数据，无需再次请求</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>Expires<span class="token operator">:</span> Wed<span class="token punctuation">,</span> <span class="token number">07</span> Apr <span class="token number">2021</span> <span class="token number">01</span><span class="token operator">:</span><span class="token number">21</span><span class="token operator">:</span><span class="token number">20</span> <span class="token constant">GMT</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>表示资源在2021年4月7日01:21:20过期，过期了就需要向服务端发请求。</p> <p>存在的问题：浏览器和服务器的时间不一致，因此时间就可能不准确。</p> <ul><li>Cache-Control</li></ul> <p>Cache-Control采用过期时长控制缓存，对应的是max-age</p> <div class="language-js line-numbers-mode"><pre class="language-js"><code>Cache<span class="token operator">-</span>Control<span class="token operator">:</span> max<span class="token operator">-</span>age<span class="token operator">=</span><span class="token number">3600</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>表示响应在3600秒后失效，也就是一个小时内都可以使用缓存。</p> <p>max-age还有其他属性</p> <div class="language-bash line-numbers-mode"><pre class="language-bash"><code>public: 客户端和代理服务器都可以缓存
private: 只有浏览器能缓存，中间的代理服务器不能缓存
no-cache: 跳过当前的强缓存，发送HTTP请求，即直接进入协商缓存阶段
no-store: 不进行任何形式的缓存
s-maxage: 类似max-age，但是这个是针对代理服务器的缓存时间
must-revalidate: 一旦缓存过期，必须回到资源服务器验证
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><ul><li>注意</li></ul> <p>当Expires和Cache-Control同时存在的时候，Cache-Control会优先考虑。<br>
强缓存失效了，就会进入协商缓存。</p> <h2 id="协商缓存"><a href="#协商缓存" class="header-anchor">#</a> 协商缓存</h2> <p>强缓存失效之后，浏览器在请求头中携带相应的缓存tag来向服务器发请求，由服务器根据这个tag，来决定是否使用缓存。</p> <ul><li>Last-Modified</li></ul> <p>即最后修改时间，在浏览器第一次给服务器发送请求后，服务器会在响应头中加上这个字段。
浏览器接收到后，如果再次请求，会在请求头中携带<code>If-Modified-Since</code>字段，这个字段的值也就是服务器传来的最后修改时间。</p> <p>服务器拿到请求头中的<code>If-Modified-Since</code>的字段后，会跟这个服务器中该资源的<strong>最后修改时间</strong>对比:</p> <ol><li>如果请求头中的这个值小于最后修改时间，说明是时候更新了。返回新的资源，跟常规的HTTP请求响应的流程一样。</li> <li>否则返回304，告诉浏览器直接用缓存。</li></ol> <ul><li>ETag</li></ul> <p>服务器给当前文件的内容的唯一标识，只有内容变动，<code>ETag</code>才会变。
浏览器接收到<code>ETag</code>的值，会在下次请求时，将这个值作为<code>If-None-Match</code>这个字段的内容，并放到请求头中，然后发给服务器。</p> <p>服务器接收到<code>If-None-Match</code>后，会跟服务器上该资源的<code>ETag</code>进行对比:</p> <ol><li>如果两者不一样，说明要更新了。返回新的资源，跟常规的HTTP请求响应的流程一样。</li> <li>否则返回304，告诉浏览器直接用缓存。</li></ol> <ul><li>注意</li></ul> <ol><li>在精准度上，<code>ETag</code>优于<code>Last-Modified</code>。 <code>ETag</code> 是按照内容给资源上标识，因此能准确感知资源的变化。而 <code>Last-Modified</code> 就不一样了，它在一些特殊的情况并不能准确感知资源变化，主要有两种情况：</li></ol> <div class="language-html line-numbers-mode"><pre class="language-html"><code>1. 编辑了资源文件，但是文件内容并没有更改，这样也会造成缓存失效。
2. Last-Modified 能够感知的单位时间是秒， 如果文件在 1 秒内改变了多次，
那么这时候的 Last-Modified 并没有体现出修改。
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><ol start="2"><li><p>在性能上，<code>Last-Modified</code>优于<code>ETag</code>，也很简单理解，<code>Last-Modified</code>仅仅只是记录一个时间点，而 <code>ETag</code>需要根据文件的具体内容生成哈希值。</p></li> <li><p>如果两种方式都支持的话，服务器会优先考虑<code>ETag</code>。</p></li></ol></div> <footer class="page-edit"><!----> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
      ←
      <a href="/blog/http/accelerate.html" class="prev">
        加速Github访问
      </a></span> <span class="next"><a href="/blog/http/http2.html">
        HTTP/2
      </a>
      →
    </span></p></div> </main></div><div class="global-ui"><!----></div></div>
    <script src="/blog/assets/js/app.17d93a93.js" defer></script><script src="/blog/assets/js/2.d5810a70.js" defer></script><script src="/blog/assets/js/53.c398474b.js" defer></script>
  </body>
</html>
